home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch14 / Bezier.cls < prev    next >
Text File  |  1999-06-23  |  7KB  |  263 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "Bezier3d"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = False
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15.  
  16. Private MaxU As Integer     ' Dimensions of control grid.
  17. Private MaxV As Integer
  18. Private Points() As Point3D ' Control points.
  19.  
  20. ' Holds polylines containing the refined
  21. ' grid to display the surface.
  22. Private Polylines As Collection
  23.  
  24. ' u and v increment parameters.
  25. Private GapU As Single
  26. Private GapV As Single
  27. Private Du As Single
  28. Private Dv As Single
  29.  
  30. ' Display flags.
  31. Private ShowControls As Boolean ' Draw control points?
  32. Private ShowGrid As Boolean     ' Draw control grid?
  33. ' Return the factorial of a number (n!).
  34. Function Factorial(ByVal n As Single) As Single
  35. Dim i As Integer
  36. Dim tot As Single
  37.  
  38.     tot = 1
  39.     For i = 2 To n
  40.         tot = tot * i
  41.     Next i
  42.     Factorial = tot
  43. End Function
  44.  
  45. ' Create polylines to represent the surface.
  46. Public Sub InitializeGrid(ByVal gap_x As Single, ByVal gap_z As Single, ByVal d_x As Single, ByVal d_z As Single)
  47. Dim u As Single
  48. Dim v As Single
  49. Dim X As Single
  50. Dim Y As Single
  51. Dim Z As Single
  52. Dim x1 As Single
  53. Dim y1 As Single
  54. Dim z1 As Single
  55. Dim pline As Polyline3d
  56.  
  57.     GapU = gap_x
  58.     GapV = gap_z
  59.     Du = d_x
  60.     Dv = d_z
  61.  
  62.     Set Polylines = New Collection
  63.  
  64.     ' Create curves with constant u.
  65.     For u = 0 To 1 + GapU / 10 Step GapU
  66.         Set pline = New Polyline3d
  67.         Polylines.Add pline
  68.  
  69.         SurfaceValue u, 0, x1, y1, z1
  70.         
  71.         For v = Dv To 1 + Dv / 10 Step Dv
  72.             SurfaceValue u, v, X, Y, Z
  73.             pline.AddSegment x1, y1, z1, X, Y, Z
  74.             x1 = X
  75.             y1 = Y
  76.             z1 = Z
  77.         Next v
  78.     Next u
  79.  
  80.     ' Create curves with constant v.
  81.     For v = 0 To 1 + GapV / 10 Step GapV
  82.         Set pline = New Polyline3d
  83.         Polylines.Add pline
  84.         
  85.         SurfaceValue 0, v, x1, y1, z1
  86.         For u = Du To 1 + Du / 10 Step Du
  87.             SurfaceValue u, v, X, Y, Z
  88.             pline.AddSegment x1, y1, z1, X, Y, Z
  89.             x1 = X
  90.             y1 = Y
  91.             z1 = Z
  92.         Next u
  93.     Next v
  94. End Sub
  95. ' Apply a transformation matrix which may not
  96. ' contain 0, 0, 0, 1 in the last column to the
  97. ' object.
  98. Public Sub ApplyFull(M() As Single)
  99. Dim i As Integer
  100. Dim j As Integer
  101. Dim pline As Polyline3d
  102.  
  103.     ' Apply the matrix to the grid if it exists.
  104.     If Not Polylines Is Nothing Then
  105.         For Each pline In Polylines
  106.             pline.ApplyFull M
  107.         Next pline
  108.     End If
  109.  
  110.     ' Apply the matrix to the control points.
  111.     For i = 0 To MaxU
  112.         For j = 0 To MaxV
  113.             m3ApplyFull Points(i, j).coord, M, Points(i, j).trans
  114.         Next j
  115.     Next i
  116. End Sub
  117. ' Draw the transformed object on a PictureBox.
  118. Public Sub Draw(ByVal pic As PictureBox, Optional R As Variant)
  119. Dim i As Integer
  120. Dim j As Integer
  121. Dim pline As Polyline3d
  122.  
  123.     ' Draw the grid if it exists.
  124.     If Not Polylines Is Nothing Then
  125.         For Each pline In Polylines
  126.             pline.Draw pic, R
  127.         Next pline
  128.     End If
  129.  
  130.     ' Draw the control points if desired.
  131.     If ShowControls Then
  132.         On Error Resume Next
  133.         For i = 0 To MaxU
  134.             For j = 0 To MaxV
  135.                 pic.Line (Points(i, j).trans(1) - 2, Points(i, j).trans(2) - 2)-Step(4, 4), , BF
  136.             Next j
  137.         Next i
  138.     End If
  139.  
  140.     ' Draw the control grid if desired.
  141.     If ShowGrid Then
  142.         On Error Resume Next
  143.         For i = 0 To MaxU
  144.             pic.CurrentX = Points(i, 0).trans(1)
  145.             pic.CurrentY = Points(i, 0).trans(2)
  146.             For j = 1 To MaxV
  147.                 pic.Line -(Points(i, j).trans(1), Points(i, j).trans(2))
  148.             Next j
  149.         Next i
  150.         For j = 0 To MaxV
  151.             pic.CurrentX = Points(0, j).trans(1)
  152.             pic.CurrentY = Points(0, j).trans(2)
  153.             For i = 1 To MaxU
  154.                 pic.Line -(Points(i, j).trans(1), Points(i, j).trans(2))
  155.             Next i
  156.         Next j
  157.     End If
  158. End Sub
  159.  
  160. ' Return a value indicating whether we
  161. ' are drawing the control grid.
  162. Property Get DrawGrid() As Boolean
  163.     DrawGrid = ShowGrid
  164. End Property
  165.  
  166. ' Return a value indicating whether we
  167. ' are drawing the control points.
  168. Property Get DrawControls() As Boolean
  169.     DrawControls = ShowControls
  170. End Property
  171.  
  172.  
  173. ' Set the value indicating whether we
  174. ' are drawing the control grid.
  175. Property Let DrawGrid(ByVal new_value As Boolean)
  176.     ShowGrid = new_value
  177. End Property
  178. ' Set the value indicating whether we
  179. ' are drawing the control points.
  180. Property Let DrawControls(ByVal new_value As Boolean)
  181.     ShowControls = new_value
  182. End Property
  183.  
  184.  
  185.  
  186.  
  187. ' Apply a transformation matrix to the object.
  188. Public Sub Apply(M() As Single)
  189. Dim i As Integer
  190. Dim j As Integer
  191. Dim pline As Polyline3d
  192.  
  193.     ' Apply the matrix to the polylines.
  194.     If Not Polylines Is Nothing Then
  195.         For Each pline In Polylines
  196.             pline.Apply M
  197.         Next pline
  198.     End If
  199.  
  200.     ' Apply the matrix to the control points.
  201.     For i = 0 To MaxU
  202.         For j = 0 To MaxV
  203.             m3Apply Points(i, j).coord, M, Points(i, j).trans
  204.         Next j
  205.     Next i
  206. End Sub
  207.  
  208.  
  209.  
  210.  
  211.  
  212. ' Set MaxU and MaxV and allocate room for the
  213. ' control points.
  214. Public Sub SetBounds(ByVal NumX As Integer, ByVal NumZ As Integer)
  215.     MaxU = NumX - 1
  216.     MaxV = NumZ - 1
  217.     ReDim Points(0 To NumX, 0 To NumZ)
  218. End Sub
  219.  
  220. ' Set the value for a control point.
  221. Public Sub SetControlPoint(ByVal i As Integer, ByVal j As Integer, ByVal X As Single, ByVal Y As Single, ByVal Z As Single)
  222.     Points(i - 1, j - 1).coord(1) = X
  223.     Points(i - 1, j - 1).coord(2) = Y
  224.     Points(i - 1, j - 1).coord(3) = Z
  225.     Points(i - 1, j - 1).coord(4) = 1
  226. End Sub
  227. ' Return the (X, Y, Z) coordinates of the
  228. ' Bezier surface for these u and v values.
  229. Private Sub SurfaceValue(ByVal u As Single, ByVal v As Single, ByRef X As Single, ByRef Y As Single, ByRef Z As Single)
  230. Dim P As Integer
  231. Dim i As Integer
  232. Dim j As Integer
  233. Dim pt As Point3D
  234. Dim Bix As Single
  235. Dim Bjz As Single
  236.  
  237.     For i = 0 To MaxU
  238.         ' Compute Bix.
  239.         Bix = Factorial(MaxU) / Factorial(i) / _
  240.             Factorial(MaxU - i) * _
  241.             u ^ i * (1 - u) ^ (MaxU - i)
  242.         
  243.         For j = 0 To MaxV
  244.             ' Compute Bjz.
  245.             Bjz = Factorial(MaxV) / Factorial(j) / _
  246.                 Factorial(MaxV - j) * _
  247.                 v ^ j * (1 - v) ^ (MaxV - j)
  248.             
  249.             ' Add to the coordinates.
  250.             For P = 1 To 3
  251.                 pt.coord(P) = pt.coord(P) + _
  252.                     Points(i, j).coord(P) * _
  253.                     Bix * Bjz
  254.             Next P
  255.         Next j
  256.     Next i
  257.     
  258.     ' Prepare the output.
  259.     X = pt.coord(1)
  260.     Y = pt.coord(2)
  261.     Z = pt.coord(3)
  262. End Sub
  263.